home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / OVLMGR.ASM < prev    next >
Assembly Source File  |  1989-11-27  |  31KB  |  1,180 lines

  1. ;    SCCS Id: @(#)ovlmgr.asm     3.0    89/11/16
  2. ;  Copyright (c) Pierre Martineau and Stephen Spackman, 1989.
  3. ;  This product may be freely redistributed.  See NetHack license for details.
  4.  
  5.         PAGE    60,132
  6.         TITLE    'Overlay manager for use with Microsoft overlay linker'
  7.         SUBTTL    'Brought to you by Pierre Martineau and Stephen Spackman'
  8.  
  9. ; acknowledgements:   - No thanks to Microsoft
  10. ;              - alltrsidsctysti!!!
  11. ;              - izchak and friends for impetus
  12. ;              - us for brilliance
  13. ;              - coffee for speed
  14. ;              - others as necessary
  15.  
  16. ; assumptions:          - all registers are preserved including flags
  17. ;              - the stack is preserved
  18. ;              - re-entrancy is not required
  19.  
  20. DOSALLOC    equ    48h            ; memory allocation
  21. DOSFREE     equ    49h            ; free allocated memory
  22. DOSREALLOC    equ    4ah            ; modify memory block
  23. DOSREAD     equ    3fh            ; read bytes from handle
  24. DOSSEEK     equ    42h            ; logical handle seek
  25. DOSOPEN     equ    3dh            ; open handle
  26. DOSCLOSE    equ    3eh            ; close handle
  27. DOSGETVEC    equ    35h            ; get interrupt vector
  28. DOSSETVEC    equ    25h            ; set interrupt vector
  29. DOSEXEC     equ    4bh            ; exec child process
  30. DOS        equ    21h            ; Dos interrupt #
  31. PRINT        equ    09h            ; print string
  32. TERMINATE    equ    4ch            ; terminate process
  33. CR        equ    0dh
  34. LF        equ    0ah
  35. BELL        equ    07h
  36. FAERIE        equ    0h            ; Used for dummy segment allocation
  37. PARSIZ        equ    10h            ; this is the size of a paragraph - this better not change!
  38.  
  39. ; The following extrns are supplied by the linker
  40.  
  41. extrn        $$OVLBASE:byte            ; segment of OVERLAY_AREA
  42. extrn        $$MPGSNOVL:byte         ; ^ to module table
  43. extrn        $$MPGSNBASE:word        ; ^ to module segment fixups
  44. extrn        $$INTNO:byte            ; interrupt number to be used
  45. extrn        $$COVL:word            ; number of physical overlays
  46. extrn        $$CGSN:word            ; number of modules
  47. extrn        $$MAIN:far            ; ^ to function main()
  48.  
  49. public        $$OVLINIT            ; Our entry point
  50.                         ; called by the c startup code
  51.  
  52. ovlflgrec    record    running:1=0,locked:1=0,loaded:1=0 ; overlay flags
  53.  
  54. ; This is a dirty hack. What we need is a virtual segment that will be built
  55. ; by the (our) loader in multiple copies, one per overlay. Unfortunately, this
  56. ; doesn't seem to be a sensible idea in the minds of the folks at Microsoft.
  57. ; Declaring this segment AT will ensure that it never appears in the exefile,
  58. ; and ASSUME is dumb enough to be fooled.
  59. ;
  60. ; The reason we want to do this is also not-to-be-tried-at-home: it turns out
  61. ; that we can code a faster interrupt handler if we map overlay numbers to
  62. ; segment values. Normally I would consider this unacceptable programming
  63. ; practise because it is 86-mode specific, but the *need* for this entire
  64. ; programme is 86-mode specific, anyway.
  65.  
  66. pspseg        segment para at FAERIE        ; dummy segment for psp
  67.         org    2ch            ; ^ to segment of environmemt in psp
  68. pspenv        LABEL    WORD
  69. pspseg        ends
  70.  
  71. ovltbl        segment para at FAERIE        ; Dummy segment definition for overlay table
  72.  
  73. ; NOTE: This segment definition MUST be exactly 16 bytes long
  74.  
  75. ovlflg        ovlflgrec    <0,0,0>     ; overlay flags
  76. ovltblpad1    db    ?            ; go ahead, delete me!
  77. ovlmemblk    dw    ?            ; ^ to allocated memory block
  78. ovlseg        dw    0            ; ovl segment physical add.
  79. ovlfiloff    dw    ?            ; ovl file offset in pages (512 bytes)
  80. ovlsiz        dw    ?            ; ovl size in paragraphs
  81. ovllrudat    dd    0            ; misc lru data (pseudo time stamp)
  82. ovltblpad2    dw    ?            ; go ahead, delete me!
  83.  
  84. if1
  85. if        $ gt PARSIZ
  86.         .err
  87.         %out This segment MUST be no more than 16 bytes, REALLY!!!
  88. endif
  89. endif
  90.  
  91. ovlsegsiz    equ    PARSIZ            ; this had better be true!!! (16 bytes)
  92.  
  93. ovltbl        ends
  94.  
  95. EXEHDR        struc                ; structure of an EXE header
  96. exesign     dw    5a4dh            ; signature
  97. exelstpgesiz    dw    ?            ; last page size (512 byte pages)
  98. exesiz        dw    ?            ; total pages (including partial last page)
  99. relocitems    dw    ?            ; number of relocation entries
  100. hdrparas    dw    ?            ; number of paragraphs in the header
  101. minalloc    dw    ?            ; minimum paragraph allocation
  102. maxalloc    dw    ?            ; maximum patagraph allocation
  103. exess        dw    ?            ; initial stack segment
  104. exesp        dw    ?            ; initial stack pointer
  105. exechksum    dw    ?            ; checksum
  106. exeip        dw    ?            ; initial instruction pointer
  107. execs        dw    ?            ; initial code segment
  108. reloctbloff    dw    ?            ; offset from beginning of header to relocation table
  109. exeovlnum    dw    ?            ; overlay number
  110. EXEHDR        ends
  111.  
  112. MASK_used    equ    1            ; memory block flag
  113.  
  114. memctlblk    struc                ; memory block structure
  115. memblkflg    db    0            ; flags
  116. memblkpad1    db    0            ; go ahead, delete me!
  117. memblknxt    dw    0            ; ^ to next block
  118. memblkprv    dw    0            ; ^ to previous block
  119. memblkovl    dw    0            ; ^ to overlay occupying this block
  120. memblksiz    dw    0            ; size in paragraphs
  121. memblkpad    db    PARSIZ - ($ - memblkflg) mod parsiz dup (?) ; pad to 16 bytes
  122. memctlblk    ends
  123.  
  124. memctlblksiz    equ    memblkpad + SIZE memblkpad ; should equal 1 paragraph (16 bytes)
  125.  
  126. ;-------------------------------------------------------------------------------
  127.  
  128. code        segment public
  129.  
  130. ovlexefilhdl    dw    -1            ; always-open file handle of our .EXE
  131. ovltim        dd    0            ; pseudo-lru time variable
  132. curovl        dw    offset framestk     ; ^ into stack frame
  133. ovlcnt        dw    0            ; # overlays
  134. modcnt        dw    0            ; # of modules
  135. ovltblbse    dw    -1            ; segment of first overlay descriptor
  136. ovlrootcode    dw    0            ; logical segment of OVERLAY_AREA
  137. ovldata     dw    0            ; logical segment of OVERLAY_END
  138. memblk1st    dw    0            ; first memory block
  139. pspadd        dw    0            ; our psp address + 10h (for relocations)
  140. oldvec        dd    -1            ; saved interrupt vector
  141. oldint21    dd    -1            ; saved int 21 vector
  142. memstat     db    0ffh            ; must we re-allocate some memory
  143. bxreg        dw    0            ; temp save area
  144. esreg        dw    0            ; temp save area
  145. farcall     dd    0            ; internal trampoline.
  146. hdr        EXEHDR    <>            ; EXE header work area
  147. hdrsize     equ    $ - hdr
  148.  
  149. framestk    dw    100h dup (0)        ; internal stack
  150.  
  151. moduletbl    dw    256*2 dup (0)        ; module lookup table
  152.  
  153. noroom        db    CR,LF,'Not enough memory to run this program.  Time to go to the store.',CR,LF,BELL,'$'
  154. nocore        db    CR,LF,'Your dog eats all your remaining memory!  You die.',CR,LF,BELL,'$'
  155. nofile        db    CR,LF,'The Nymph stole your .EXE file!  You die.',CR,LF,BELL,'$'
  156. exitmsg     db    CR,LF,'$'
  157.  
  158. ;-------------------------------------------------------------------------------
  159.  
  160. $$OVLINIT    proc    far            ; Init entry point
  161.  
  162.         assume    cs:code,ds:pspseg,es:nothing
  163.  
  164.         push    ax
  165.         push    bx
  166.         push    cx
  167.         push    dx
  168.         push    si
  169.         push    di
  170.         push    bp
  171.         push    ds
  172.         push    es            ; save the world
  173.         mov    ax,ds            ; get our psp
  174.         add    ax,10h
  175.         mov    pspadd,ax        ; save it
  176.         mov    ds,pspenv        ; get environment segment
  177.         mov    si,-1
  178. envloop:                    ; search for end of environment
  179.         inc    si
  180.         cmp    word ptr [si],0
  181.         jnz    envloop
  182.         add    si,4            ; point to EXE filename
  183.         mov    al,0            ; access code
  184.         mov    ah,DOSOPEN
  185.         mov    dx,si
  186.         int    DOS            ; open EXE
  187.         jnc    dontdie
  188.         mov    al,5
  189.         mov    dx,offset nofile
  190.         jmp    putserr         ; cry to the world!
  191. dontdie:
  192.         mov    ovlexefilhdl,ax     ; save handle
  193.         mov    ax,SEG $$OVLBASE    ; OVERLAY_AREA segment
  194.         mov    ovlrootcode,ax
  195.  
  196. ; Now allocate memory
  197.         mov    bx,0900h        ; allocate memory for malloc()
  198.         mov    ah,DOSALLOC
  199.         int    DOS
  200.         jnc    getmore
  201.         jmp    buyram
  202. getmore:
  203.         mov    es,ax            ; find largest free memory
  204.         mov    ah,DOSALLOC
  205.         mov    bx,0ffffh        ; Everything
  206.         int    DOS
  207.         mov    ah,DOSALLOC        ; allocate our own memory
  208.         int    DOS
  209.         jnc    gotitall
  210.         jmp    buyram
  211. gotitall:
  212.         mov    memstat,0        ; indicate that we have memory
  213.         mov    ovltblbse,ax        ; overlay descriptor table begins at start of memory block
  214.         mov    ax,SEG $$COVL        ; segment of DGROUP
  215.         mov    ds,ax
  216.         mov    cx,$$CGSN        ; number of modules
  217.         mov    modcnt,cx        ; save for later use
  218.         mov    cx,$$COVL        ; number of physical overlays
  219.         mov    ovlcnt,cx        ; save for later use
  220.         sub    bx,cx            ; enough mem for ovl tbl?
  221.         jnc    memloop
  222.         jmp    buyram
  223. memloop:
  224.         push    bx
  225.         mov    ah,DOSFREE        ; free first block for malloc()
  226.         int    DOS
  227.         jnc    cockadoodledoo
  228.         jmp    buyram
  229. cockadoodledoo:
  230.  
  231.         assume    es:ovltbl
  232.  
  233.         xor    bp,bp
  234.         xor    di,di
  235.         xor    si,si
  236. filsegtbllpp:                    ; initialise ovl table
  237.         call    gethdr            ; get an EXE header
  238.         mov    ax,ovltblbse
  239.         add    ax,hdr.exeovlnum
  240.         mov    es,ax            ; ^ to ovl table entry
  241.         xor    ax,ax
  242.         mov    word ptr ovllrudat,ax    ; initialise ovl lru
  243.         mov    word ptr ovllrudat+2,ax
  244.         mov    ovlseg,ax        ; initialise ovl segment
  245.         mov    ovlflg,al        ; initialise ovl flags
  246.         mov    ax,hdr.exesiz
  247.         shl    ax,1
  248.         shl    ax,1
  249.         shl    ax,1
  250.         shl    ax,1
  251.         shl    ax,1            ; * 32
  252.         mov    dx,hdr.exelstpgesiz
  253.         or    dx,dx
  254.         jz    emptypage
  255.         shr    dx,1
  256.         shr    dx,1
  257.         shr    dx,1
  258.         shr    dx,1            ; / 16
  259.         inc    dx
  260.         sub    ax,20h
  261.         add    ax,dx
  262. emptypage:
  263.         mov    ovlsiz,ax        ; overlay size in paragraphs
  264.         sub    ax,hdr.hdrparas     ; actual size of